package cn.wsalix.biz.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Observable;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.anlaser.admin.BaseUser;
import cn.anlaser.form.UploadFileForm;
import cn.anlaser.service.impl.ParentServiceImpl;
import cn.anlaser.status.FlagEnum;
import cn.anlaser.type.FileTypeEnum;
import cn.anlaser.type.ImageTypeEnum;
import cn.anlaser.utils.SearchFilter;
import cn.anlaser.utils.SearchFilter.Operator;
import cn.wsalix.biz.entity.Category;
import cn.wsalix.biz.entity.RelationCat;
import cn.wsalix.biz.form.CategoryForm;
import cn.wsalix.biz.repository.CategoryRepository;
import cn.wsalix.biz.repository.RelationCatRepository;
import cn.wsalix.biz.service.CategoryService;
import cn.wsalix.biz.type.CatTypeEnum;
import cn.wsalix.observable.service.FileUploadService;
import cn.wsalix.shop.service.ShopService;
import cn.wsalix.status.CatEnum;

@Service("categoryService")
public class CategoryServiceImpl extends
		ParentServiceImpl<CategoryForm, CategoryRepository, Category> implements
		CategoryService {
	@Autowired
	private CategoryRepository categoryRepository;
	@Autowired
	private RelationCatRepository relationCatRepository;
	@Autowired
	private ShopService shopService;

	@Override
	public String module() {
		return "/biz/cat";
	}

	@Override
	public CategoryRepository getRepository() {
		return categoryRepository;
	}

	@Override
	public Category add(CategoryForm form) {
		Category obj = categoryRepository.findOne(form.getId());
		/*
		 * if (form.getShop() != null) { obj.setShop(form.getShop()); } else if
		 * (form.getShopId() != null && form.getShopId() != 0) { Shop shop =
		 * shopService.findById(form.getShopId()); obj.setShop(shop); }
		 */
		traversalAssign(form, obj);
		obj.setFlag(FlagEnum.valid);
		obj = add(obj);

		return obj;
	}

	@Transactional
	@Override
	public Category edit(CategoryForm form) {
		Category entity = categoryRepository.findOne(form.getId());
		if (form.getUploadType() != null) {
			if (form.getUploadType().equals("header")) {
				entity.setHeaderImg(form.getFilePath());
			}
			if (form.getUploadType().equals("logo")) {
				entity.setLogo(form.getFilePath());
			}
			if (form.getUploadType().equals("footer")) {
				entity.setFooterImg(form.getFilePath());
			}
		}
		traversalAssign(form, entity);
		logger.info(form.getFilePath());
		return super.edit(entity);
	}

	@Override
	public Class<Category> getEntityClazz() {
		return Category.class;
	}

	@Transactional
	@Override
	public void delete(Long id) {
		relationCatRepository.deleteByCatId(id);
		super.delete(id);
	}

	@Override
	public List<Category> findByForm(CategoryForm form) {
		if (form.getShopId() != null && form.getShopId() != 0) {
			return relationCatRepository.findByShopId(form.getShopId(), CatTypeEnum.shop,
					form.getCreatedBy(), FlagEnum.valid);
		}
		return super.findByForm(form);
	}

	@Override
	public Map<String, SearchFilter> buildByForm(CategoryForm form) {
		Map<String, SearchFilter> filters = buildFilter(form);
		if (form.getParentId() != null && form.getParentId() != 0) {
			filters.put("parent.id", new SearchFilter("parent.id", Operator.EQ,
					form.getParentId()));
		}
		if (form.getStatus() != null) {
			filters.put("status",
					new SearchFilter("status", Operator.EQ, form.getStatus()));
		}
		if (form.isParentNull()) {
			filters.put("parent", new SearchFilter("parent.id",
					Operator.ISNULL, null));
		}
		return filters;
	}

	@Transactional
	@Override
	public void update(Observable o, Object arg) {
		if (o instanceof FileUploadService) {
			FileUploadService fileUploadService = (FileUploadService) o;
			if (arg instanceof UploadFileForm) {
				UploadFileForm obj = (UploadFileForm) arg;
				if (obj.getType().ordinal() == FileTypeEnum.image.ordinal()) {
					if (obj.getImageType().equals( ImageTypeEnum.category.name())) {// 用户头像
						// if (obj.getCode() != null &&
						// obj.getCode().equals("logo")) {
						if (obj.getFkId() != 0) {
							Category category = categoryRepository.findOne(obj
									.getFkId());
							category.setLogo(obj.getHttpUrl());
							super.edit(category);
							// fileUploadService.setObj(category);
						}

					}
				}
			}
		}
	}
	
	@Override
	public Category findByCodeOne(String code) {
		logger.info(code);
		List<Category> menus = findsByCode(code);
		if (menus.size() != 1) {
			if (menus.size() > 1) {
				logger.error(code + " : size() > 1 [" + menus.size() + "]");
				return menus.get(0);
			}
			logger.error(code + " : size() =0 ");
			return null;
		} else {
			return menus.get(0);
		}
	}

	@Override
	public List<Category> findsByCode(String code) {
		return categoryRepository.findByCode(code);
	}

	@Override
	public List<Category> findSubsByCode(String code) {
		Category parent = findByCodeOne(code);
		return findSubsById(parent.getId());
	}

	@Override
	public List<Category> findSubsById(Long parentId) {
		CategoryForm form = new CategoryForm();
		form.setParentId(parentId);
		form.setStatus(CatEnum.release);
		return findByForm(form);
	}

	@Transactional
	@Override
	public Category getNew() {
		BaseUser user = userUtils.getUser();
		CategoryForm form = new CategoryForm();
		form.setFlag(FlagEnum.create);
		form.setCreatedBy(user.getId());
		List<Category> resLst = findByForm(form);
		if (!resLst.isEmpty()) {
			return resLst.get(0);
		} else {
			Category cat = new Category();
			cat.setFlag(FlagEnum.create);
			cat.setCreatedBy(user.getId());
			cat.setCreatedDate(new Date());
			return add(cat);
		}

	}

	@Transactional
	@Override
	public Category getNew(Long shopId, CatTypeEnum catType) {
		Category category = getNew();
		RelationCat relationCat = new RelationCat();
		relationCat.setFkId(shopId);
		relationCat.setCatType(catType);
		relationCat.setCategory(category);
		relationCatRepository.save(relationCat);
		return category;
	}

	@Override
	public List<Category> findByUnShopId(Long shopId, Long userId) {
		List<Category> resultLst = relationCatRepository.findByShopId(shopId,
				CatTypeEnum.shop, userId, FlagEnum.valid);
		CategoryForm form = new CategoryForm();
		form.setFlag(FlagEnum.valid);
		form.setCreatedBy(userId);
		List<Category> srcLst = findByForm(form);
		List<Category> resLst = new ArrayList<Category>();
		for (Category category : srcLst) {
			if (resultLst.contains(category)) {
				category.setSelect(true);
			}
			resLst.add(category);
		}
		return resLst;
	}
}
